from django.shortcuts import render
from rest_framework import viewsets, permissions, status
from rest_framework.response import Response
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from .models import MCPServer, MCPServerFromReadme, MCPServerTag
from .serializers import MCPServerSerializer, UserSerializer, MCPServerFromReadmeSerializer
from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.contrib.auth.hashers import make_password
import os
import json
import subprocess
import tempfile
from datetime import datetime
from django.http import HttpResponse, JsonResponse
from django.conf import settings
import requests
from rest_framework.views import APIView
from django.db import models
from rest_framework.exceptions import PermissionDenied

# Create your views here.

@api_view(['POST', 'OPTIONS'])
@permission_classes([permissions.AllowAny])
@csrf_exempt
def register_user(request):
    """用户注册API"""
    # 处理预检请求
    if request.method == 'OPTIONS':
        response = Response()
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
        response['Access-Control-Allow-Headers'] = 'X-Requested-With, Content-Type, Authorization'
        return response
        
    username = request.data.get('username')
    email = request.data.get('email')
    password = request.data.get('password')
    
    if not username or not email or not password:
        return Response(
            {'detail': '用户名、邮箱和密码不能为空'},
            status=status.HTTP_400_BAD_REQUEST
        )
    
    if User.objects.filter(username=username).exists():
        return Response(
            {'detail': '用户名已存在'},
            status=status.HTTP_400_BAD_REQUEST
        )
    
    if User.objects.filter(email=email).exists():
        return Response(
            {'detail': '邮箱已被使用'},
            status=status.HTTP_400_BAD_REQUEST
        )
    
    user = User.objects.create_user(
        username=username,
        email=email,
        password=password
    )
    
    response = Response(
        {'detail': '注册成功'},
        status=status.HTTP_201_CREATED
    )
    
    # 添加CORS头以确保正确响应
    response["Access-Control-Allow-Origin"] = "*"
    return response

@api_view(['POST', 'OPTIONS'])
@permission_classes([permissions.AllowAny])
@csrf_exempt
def login_user(request):
    """标准登录API"""
    # 处理预检请求
    if request.method == 'OPTIONS':
        response = Response()
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
        response['Access-Control-Allow-Headers'] = 'X-Requested-With, Content-Type, Authorization'
        return response
        
    username = request.data.get('username')
    password = request.data.get('password')
    
    if not username or not password:
        return Response(
            {'non_field_errors': ['用户名和密码不能为空']},
            status=status.HTTP_400_BAD_REQUEST
        )
    
    user = authenticate(username=username, password=password)
    
    if user is not None:
        login(request, user)
        
        # 创建登录响应
        response = Response({
            'key': 'session-auth',
            'user_id': user.id,
            'username': user.username
        })
        response['Access-Control-Allow-Origin'] = '*'
        return response
    else:
        return Response(
            {'non_field_errors': ['无效的用户名或密码']},
            status=status.HTTP_400_BAD_REQUEST
        )

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_user(request):
    """获取当前登录用户"""
    serializer = UserSerializer(request.user)
    return Response(serializer.data)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def logout_user(request):
    """用户登出"""
    logout(request)
    return Response({"detail": "成功退出登录"})

class IsOwnerOrReadOnly(permissions.BasePermission):
    """自定义权限，只允许对象的所有者编辑它"""
    
    def has_permission(self, request, view):
        # 读取方法总是允许的
        if request.method in permissions.SAFE_METHODS:
            return True
        # 写入方法需要用户已登录
        return request.user and request.user.is_authenticated
    
    def has_object_permission(self, request, view, obj):
        # 读取权限允许任何请求
        if request.method in permissions.SAFE_METHODS:
            return True
        
        # 写入权限只允许对象的所有者
        return obj.owner == request.user

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """用户视图集，只读"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated, TokenHasReadWriteScope]
    
    @action(detail=False, methods=['get'])
    def me(self, request):
        """获取当前登录用户信息"""
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)

class MCPServerViewSet(viewsets.ModelViewSet):
    """用户添加的MCP服务器视图集"""
    queryset = MCPServer.objects.all().order_by('-created_at')
    serializer_class = MCPServerSerializer
    permission_classes = [IsOwnerOrReadOnly]  # 只保留所有者权限检查，读取操作允许任何人
    
    def perform_create(self, serializer):
        # 创建服务器时，用户必须已登录
        if not self.request.user.is_authenticated:
            raise PermissionDenied("必须登录才能添加服务器")
        serializer.save(owner=self.request.user)

class ServerViewSet(viewsets.ReadOnlyModelViewSet):
    """
    API端点，提供MCP服务器数据。
    目前数据来自解析的README，未来可能添加其他数据源。
    """
    queryset = MCPServerFromReadme.objects.all()
    serializer_class = MCPServerFromReadmeSerializer
    permission_classes = [permissions.AllowAny]
    
    def get_queryset(self):
        queryset = MCPServerFromReadme.objects.all()
        
        # 筛选分类
        category = self.request.query_params.get('category', None)
        if category:
            queryset = queryset.filter(category=category)
            
        # 筛选分类名称
        category_name = self.request.query_params.get('category_name', None)
        if category_name:
            queryset = queryset.filter(category_name=category_name)
        
        # 筛选标签
        tag = self.request.query_params.get('tag', None)
        if tag:
            queryset = queryset.filter(tags__contains=[tag])
        
        # 筛选语言
        language = self.request.query_params.get('language', None)
        if language:
            queryset = queryset.filter(language__contains=[language])
        
        # 搜索
        search = self.request.query_params.get('search', None)
        if search:
            queryset = queryset.filter(name__icontains=search) | \
                      queryset.filter(description__icontains=search) | \
                      queryset.filter(provider__icontains=search)
        
        return queryset
    
    @action(detail=True, methods=['get'])
    def readme(self, request, pk=None):
        """获取服务器对应仓库的README内容"""
        server = self.get_object()
        
        if not server.github:
            return Response({"error": "该服务器没有GitHub仓库链接"}, status=status.HTTP_404_NOT_FOUND)
        
        try:
            # 从GitHub URL中提取用户名和仓库名
            parts = server.github.strip('/').split('/')
            if len(parts) < 5:
                return Response({"error": "无效的GitHub URL"}, status=status.HTTP_400_BAD_REQUEST)
                
            username = parts[-2]
            repo = parts[-1]
            
            # 获取README内容
            raw_url = f"https://raw.githubusercontent.com/{username}/{repo}/main/README.md"
            response = requests.get(raw_url)
            
            if response.status_code != 200:
                # 尝试master分支
                raw_url = f"https://raw.githubusercontent.com/{username}/{repo}/master/README.md"
                response = requests.get(raw_url)
            
            if response.status_code == 200:
                return Response({"content": response.text})
            else:
                return Response({"error": "无法获取README内容"}, status=status.HTTP_404_NOT_FOUND)
        
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def parse_readme(request):
    """
    解析README文件并将数据存入数据库。
    请求体应包含：
    {
        "readme_path": "README-zh.md的路径"
    }
    """
    readme_path = request.data.get('readme_path')
    if not readme_path:
        return Response({"error": "缺少readme_path参数"}, status=status.HTTP_400_BAD_REQUEST)
    
    if not os.path.exists(readme_path):
        return Response({"error": f"找不到文件：{readme_path}"}, status=status.HTTP_404_NOT_FOUND)
    
    try:
        # 设置默认输出到backend/scripts/mcp_server_list.json
        output_json = os.path.join(settings.BASE_DIR, 'scripts', 'mcp_server_list.json')
        os.makedirs(os.path.dirname(output_json), exist_ok=True)
        
        # 运行解析脚本
        script_path = os.path.join(settings.BASE_DIR, 'scripts', 'parse_readme.py')
        db_path = os.path.join(settings.BASE_DIR, 'db.sqlite3')
        
        cmd = [
            'python', script_path,
            '--readme', readme_path,
            '--output', output_json,
            '--db', db_path
        ]
        
        result = subprocess.run(cmd, capture_output=True, text=True)
        
        if result.returncode != 0:
            return Response({
                "error": "解析脚本执行失败",
                "stdout": result.stdout,
                "stderr": result.stderr
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        # 读取JSON结果
        with open(output_json, 'r', encoding='utf-8') as f:
            parsed_data = json.load(f)
        
        return Response({
            "message": "README解析成功",
            "total": parsed_data.get('count', 0),
            "last_updated": parsed_data.get('last_updated')
        })
    
    except Exception as e:
        return Response({
            "error": f"处理失败: {str(e)}"
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['POST', 'OPTIONS'])
@permission_classes([permissions.AllowAny])
@csrf_exempt
def debug_oauth(request):
    """调试OAuth错误"""
    from django.conf import settings
    import json
    
    # 处理预检请求
    if request.method == 'OPTIONS':
        response = Response()
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
        response['Access-Control-Allow-Headers'] = 'X-Requested-With, Content-Type, Authorization'
        return response
    
    # 检查请求数据
    try:
        request_data = {}
        if request.content_type == 'application/json':
            request_data = request.data
        elif request.content_type == 'multipart/form-data':
            request_data = request.POST.copy()
            for key in request.FILES:
                request_data[key] = request.FILES[key]
        else:
            request_data = request.POST.copy() or request.data
        
        # 检查必要的OAuth参数
        required_params = ['grant_type', 'client_id', 'client_secret', 'username', 'password']
        missing_params = [param for param in required_params if param not in request_data]
        
        data = {
            'request_method': request.method,
            'content_type': request.content_type,
            'missing_params': missing_params,
            'available_params': list(request_data.keys()),
            'oauth2_settings': {
                'scopes': settings.OAUTH2_PROVIDER.get('SCOPES', {}),
                'allowed_redirect_uri_schemes': settings.OAUTH2_PROVIDER.get('ALLOWED_REDIRECT_URI_SCHEMES', []),
            },
            'installed_apps': settings.INSTALLED_APPS,
        }
        
        return Response(data)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['POST'])
@permission_classes([permissions.IsAdminUser])
def reset_admin_password(request):
    """重置管理员密码"""
    try:
        admin = User.objects.get(username='admin')
        new_password = request.data.get('new_password')
        if not new_password:
            return Response(
                {'detail': '新密码不能为空'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        admin.password = make_password(new_password)
        admin.save()
        return Response({'detail': '管理员密码重置成功'})
    except User.DoesNotExist:
        return Response(
            {'detail': '管理员账号不存在'},
            status=status.HTTP_404_NOT_FOUND
        )

@api_view(['DELETE'])
@permission_classes([permissions.IsAdminUser])
def delete_user(request, user_id):
    """删除指定用户"""
    try:
        user = User.objects.get(id=user_id)
        if user.username == 'admin':
            return Response(
                {'detail': '不能删除管理员账号'},
                status=status.HTTP_400_BAD_REQUEST
            )
        user.delete()
        return Response({'detail': '用户删除成功'})
    except User.DoesNotExist:
        return Response(
            {'detail': '用户不存在'},
            status=status.HTTP_404_NOT_FOUND
        )

@api_view(['DELETE'])
@permission_classes([permissions.IsAdminUser])
def delete_all_users(request):
    """删除所有非管理员用户"""
    try:
        # 获取所有非管理员用户
        users = User.objects.exclude(username='admin')
        count = users.count()
        users.delete()
        return Response({
            'detail': f'成功删除 {count} 个用户',
            'deleted_count': count
        })
    except Exception as e:
        return Response(
            {'detail': f'删除用户时发生错误: {str(e)}'},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

class CategoryListView(APIView):
    """获取所有服务器分类"""
    permission_classes = [permissions.AllowAny]  # 允许任何人访问
    
    def get(self, request):
        # 从数据库获取所有分类，确保去重
        categories = MCPServerFromReadme.objects.values('category', 'category_name').distinct().order_by('category_name')
        
        # 统计每个分类下的服务器数量
        result = []
        seen_categories = set()  # 用于跟踪已添加的分类
        
        for category in categories:
            # 确保分类名称不重复
            if category['category_name'] in seen_categories:
                continue
                
            seen_categories.add(category['category_name'])
            count = MCPServerFromReadme.objects.filter(category_name=category['category_name']).count()
            result.append({
                'id': category['category_name'],  # 使用category_name作为id
                'name': category['category_name'],
                'count': count
            })
        return Response(result)

class TagListView(APIView):
    """获取所有标签"""
    permission_classes = [permissions.AllowAny]  # 允许任何人访问
    
    def get(self, request):
        # 获取所有标签及其使用频率
        tags = MCPServerTag.objects.values('tag').annotate(count=models.Count('tag')).order_by('-count')
        return Response(tags)
